#ifndef CHARACTERS_H
#define CHARACTERS_H

#include "../sprite_handler.h"
#include "player.h"
#include "turret.h"
#include "laser.h"
#include "explosion.h"
#include "enemy.h"

void handleCollision( SpriteHandler *, SpriteHandler * );
BOOL getMapCoordinates( SpriteHandler const * sprite, int *, int * );
void updateCharacter( SpriteHandler * );

// Character types found in the game
// will be changed
// typedef enum
// {
	// CHAR_NONE = 0,
	// CHAR_PLAYER,
	// CHAR_HEALTH,
	// CHAR_UPGARDE,
	// CHAR_ENEMY1,
	// CHAR_ENEMY2,
	// CHAR_ENEMY_TURRENT,
	// CHAR_ENEMY_BOSS
// } CharacterType;

void updateCharacter( SpriteHandler * character )
{
	switch ( character->characterType )
	{
		case CHAR_PLAYER:
			playerUpdateFunction( character );
			break;
		case CHAR_ENEMY_TURRENT:
			turretUpdateFunction( character );
			break;
		case CHAR_LASER:
			laserUpdateFunction( character );
			break;
		case CHAR_EXPLOSION:
			updateExplosion( character );
			break;
		case CHAR_ENEMY:
		  EnemyUpdateFunction( character );
		  break;
		default:
			break;
	}
}

// Return the map coordinates of the sprites, if the sprite has no map coordinates, false is returned.
BOOL getMapCoordinates( SpriteHandler const * sprite, int * x, int * y )
{
	// set error values
	*x = -1;
	*y = -1;
	
	switch ( sprite->characterType )
	{
		case CHAR_NONE:
		{
			break;
		}
		case CHAR_PLAYER:
		{
			PlayerData const * udata = (PlayerData const*) sprite->userData;
			
			*x = udata->map_position_x;
			*y = udata->map_position_y;
			
			break;
		}
		case CHAR_HEALTH:
		{
			break;
		}
		case CHAR_UPGARDE:
		{
			break;
		}
		case CHAR_ENEMY1:
		{
			break;
		}
		case CHAR_ENEMY2:
		{
			break;
		}
		case CHAR_ENEMY_TURRENT:
		{
			TurretData const * udata = (TurretData const*) sprite->userData;
			
			*x = udata->map_position_x;
			*y = udata->map_position_y;
			break;
		}
		case CHAR_ENEMY_BOSS:
		{
			break;
		}
		case CHAR_LASER:
		{
			LaserData const * udata = (LaserData const*) sprite->userData;
			
			*x = udata->map_position_x;
			*y = udata->map_position_y;
			break;
		}
		case CHAR_EXPLOSION:
		{
			ExplosionData const * udata = (ExplosionData const*) sprite->userData;
			
			*x = udata->map_position_x;
			*y = udata->map_position_y;
			break;
		}
		case CHAR_ENEMY:
		{
		    EnemyData const * udata = (EnemyData const*) sprite->userData;
			*x = udata->map_position_x;
			*y = udata->map_position_y;
			break;
        }
		default:
		{
			break;
		}
	}

	// Make sure it was assigned
	if ( *x == -1 ||
		 *y == -1 )
	{
		return false;
	}
	
	return true;
}

// Call the collision event for each sprite involved in this hullabaloo
void handleCollision( SpriteHandler * a, SpriteHandler * b )
{
	switch ( a->characterType )
	{
		case CHAR_NONE:
		{
			break;
		}
		case CHAR_PLAYER:
		{
			playerHandleCollision( a, b );
			break;
		}
		case CHAR_HEALTH:
		{
			break;
		}
		case CHAR_UPGARDE:
		{
			break;
		}
		case CHAR_ENEMY1:
		{
			break;
		}
		case CHAR_ENEMY2:
		{
			break;
		}
		case CHAR_ENEMY_TURRENT:
		{
			turretHandleCollision( a, b );
			break;
		}
		case CHAR_ENEMY_BOSS:
		{
			break;
		}
		case CHAR_LASER:
		{
			break;
		}
		default:
		{
			break;
		}
	}
	
	switch ( b->characterType )
	{
		case CHAR_NONE:
		{
			break;
		}
		case CHAR_PLAYER:
		{
			playerHandleCollision( b, a );
			break;
		}
		case CHAR_HEALTH:
		{
			break;
		}
		case CHAR_UPGARDE:
		{
			break;
		}
		case CHAR_ENEMY1:
		{
			break;
		}
		case CHAR_ENEMY2:
		{
			break;
		}
		case CHAR_ENEMY_TURRENT:
		{
			turretHandleCollision( b, a );
			break;
		}
		case CHAR_ENEMY_BOSS:
		{
			break;
		}
		case CHAR_LASER:
		{
			break;
		}
		default:
		{
			break;
		}
	}
}

#endif
